<template>
  <div class="container">
    <!-- 订单详情卡片 -->
    <el-card>
      <template #header>
        <div class="card-header">
          <span>订单详情</span>
        </div>
      </template>
      <div class="content">
        <!-- 顶部动态展示预约的三种状态orderStatus：0:待支付 1:已支付 -1:取消 -->
        <div class="top">
          <!-- 通过动态类名实现不同样式 -->
          <div
            class="info"
            :class="{
              success: orderInfo?.orderStatus === 1,
              cancel: orderInfo?.orderStatus == -1,
            }"
          >
            <!-- 通过v-if展示不同的图标 -->
            <SvgIcon
              v-if="orderInfo?.orderStatus == 0"
              name="wait"
              style="margin: 0 8px"
            />
            <SvgIcon
              v-else-if="orderInfo?.orderStatus == 1"
              name="yes"
              style="margin: 0 8px"
            />
            <SvgIcon
              v-else="orderInfo?.orderStatus == -1"
              name="no"
              style="margin: 0 8px"
            />
            <!-- 文字内容根据每次请求返回的数据动态展示 -->
            <p>{{ orderInfo?.param.orderStatusString }}</p>
          </div>
          <div class="tips">
            <img src="../../../assets/images/code_app.png" alt="二维码" />
            <div>
              微信
              <SvgIcon
                name="weixin"
                style="margin-bottom: -2px"
                width="16px"
                height="16px"
              />
              关注"北京114预约挂号"快速预约挂号
            </div>
          </div>
        </div>
        <div class="center">
          <!-- 左侧订单详情卡片 -->
          <div class="left">
            <el-descriptions :column="1" size="large" border>
              <el-descriptions-item label-align="right">
                <template #label>
                  <div class="cell-item">就诊人姓名</div>
                </template>
                {{ orderInfo?.patientName }}
              </el-descriptions-item>
              <el-descriptions-item label-align="right">
                <template #label>
                  <div class="cell-item">就诊日期</div>
                </template>
                {{ orderInfo?.reserveDate }}
              </el-descriptions-item>
              <el-descriptions-item label-align="right">
                <template #label>
                  <div class="cell-item">就诊医院</div>
                </template>
                {{ orderInfo?.hosname }}
              </el-descriptions-item>
              <el-descriptions-item label-align="right">
                <template #label>
                  <div class="cell-item">就诊科室</div>
                </template>
                {{ orderInfo?.depname }}
              </el-descriptions-item>
              <el-descriptions-item label-align="right">
                <template #label>
                  <div class="cell-item">医生职称</div>
                </template>
                {{ orderInfo?.title }}
              </el-descriptions-item>
              <el-descriptions-item label-align="right">
                <template #label>
                  <div class="cell-item">挂号费用</div>
                </template>
                <span style="color: crimson">{{ orderInfo?.amount }} 元</span>
              </el-descriptions-item>
              <el-descriptions-item label-align="right">
                <template #label>
                  <div class="cell-item">挂号订单</div>
                </template>
                {{ orderInfo?.id }}
              </el-descriptions-item>
              <el-descriptions-item label-align="right">
                <template #label>
                  <div class="cell-item">挂号时间</div>
                </template>
                {{ orderInfo?.createTime }}
              </el-descriptions-item>
            </el-descriptions>
          </div>
          <!-- 右侧注意事项卡片 -->
          <div class="right">
            <el-card shadow="never">
              <template #header>
                <div class="card-header">注意事项：</div>
              </template>
              <ol>
                <li>
                  请确认就诊人信息是否准确，若填写错误将无法取号就诊，损失由本人承担；
                </li>
                <li>
                  【取号】就诊当天需在
                  <span style="color: skyblue">
                    {{ orderInfo?.fetchTime.slice(10, 15) }}
                  </span>
                  前在医院
                  <span style="color: skyblue">
                    {{ orderInfo?.fetchAddress }}
                  </span>
                  取号，未取号视为爽约，该号不退不换；
                </li>
                <li>
                  【退号】在
                  <span style="color: hotpink">{{ orderInfo?.quitTime }}</span>
                  前可在线退号 ，逾期将不可办理退号退费；
                </li>
                <li>
                  北京114预约挂号支持自费患者使用身份证预约，同时支持北京市医保患者使用北京社保卡在平台预约挂号。请于就诊当日，携带预约挂号所使用的有效身份证件到院取号；
                </li>
                <li>
                  请注意北京市医保患者在住院期间不能使用社保卡在门诊取号。
                </li>
              </ol>
            </el-card>
          </div>
        </div>
      </div>
      <!-- 卡片底部的按钮 -->
      <template #footer>
        <div class="bottom">
          <!-- 动态展示底部按钮 -->
          <!-- 待支付 -->
          <div v-if="orderInfo?.orderStatus == 0">
            <el-popconfirm
              width="220"
              confirm-button-text="确定"
              cancel-button-text="返回"
              icon="CircleCloseFilled"
              icon-color="orange"
              title="你确定要取消当前预约吗?"
              @confirm="cancelOrder"
            >
              <template #reference>
                <el-button>取消预约</el-button>
              </template>
            </el-popconfirm>
            <!-- 立即支付 -->
            <el-button type="primary" @click="pay">立即支付</el-button>
          </div>
          <!-- 支付成功 -->
          <div v-else-if="orderInfo?.orderStatus == 1">
            <el-button @click="goBooking">继续挂号</el-button>
            <el-button type="primary" @click="goAllOrder">
              查看全部订单
            </el-button>
          </div>
          <!-- 取消支付 -->
          <div v-else>
            <el-button type="primary" @click="goBooking">返回挂号页</el-button>
          </div>
        </div>
      </template>
    </el-card>
    <!-- 支付对话框 
      v-model：控制显示与隐藏
      lock-scroll：禁止滚动
      close-on-click-modal：是否可以通过点击遮罩层关闭对话框
      align-center：对话框垂直居中
     -->
    <el-dialog
      v-model="dialogVisible"
      lock-scroll
      :close-on-click-modal="false"
      align-center
      width="400"
      title="微信支付"
      @close="cancelPay"
    >
      <div class="content">
        <div class="qrCode">
          <img :src="imgUrl" alt="qrCode" />
        </div>
        <p>请使用微信扫一扫</p>
        <p>扫描二维码支付</p>
      </div>
      <!-- 使用插槽自定义底部内容 -->
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="cancelPay">取消支付</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts" name="OrderDetail">
import {
  reqCancelOrder,
  reqOrderDetail,
  reqPayStatus,
  reqQrCode,
} from '@/api/user'
import type { OrderInfo } from '@/api/user/type'
import { ElMessage } from 'element-plus'
import { onMounted, ref } from 'vue'
import { useRoute, useRouter } from 'vue-router'
// 引入qrcode插件，用于生成二维码
// @ts-ignore
import QRCode from 'qrcode'

// 获取路由对象
const route = useRoute()
// 获取路由器对象
const router = useRouter()
// 存储当前订单id
let orderId = ref(Number(route.query.orderId))
// 存储当前订单的数据
let orderInfo = ref<OrderInfo>()
// 控制支付对话框 显示/隐藏
let dialogVisible = ref(false)
// 存储将服务器返回的微信支付的URL转换成的二维码
let imgUrl = ref('')
// 存储轮询支付状态的定时器
let timer = ref(0)

// 获取当前订单数据的方法
const getOrderDetail = async () => {
  let result = await reqOrderDetail(orderId.value)
  if (result.code === 200) {
    // 存储当前订单数据
    orderInfo.value = result.data
  } else {
    ElMessage.error('获取订单详情失败')
  }
}
// 点击支付按钮的回调
const pay = async () => {
  // 显示支付对话框
  dialogVisible.value = true
  // 发请求获取支付二维码
  let result = await reqQrCode(orderId.value)
  if (result.code == 200) {
    // 将服务器返回的字符串URL("weixin://wxpay/bizpayurl?pr=agDyP8oz1")生成为图片地址("data:image/png;base64,...")
    imgUrl.value = await QRCode.toDataURL(result.data.codeUrl)
  } else {
    ElMessage.error('获取支付二维码失败')
  }
  // 长轮询支付状态(只要支付二维码出现,每隔2秒向服务器询问支付状态一次)
  timer.value = setInterval(async () => {
    let result = await reqPayStatus(orderId.value)
    // 支付成功：result.data为true
    if (result.code == 200 && result.data == true) {
      // 关闭对话框
      dialogVisible.value = false
      // 提示支付成功
      ElMessage.success('支付成功')
      // 清除定时器
      clearInterval(timer.value)
      // 重新获取订单详情数据
      getOrderDetail()
    }
  }, 2000)
}
// 取消支付按钮的回调
const cancelPay = () => {
  // 关闭支付对话框
  dialogVisible.value = false
  // 关闭定时器
  clearInterval(timer.value)
}
// 取消订单的回调 订单状态：-1:取消预约 0:待支付 1:已支付
const cancelOrder = async () => {
  let result = await reqCancelOrder(orderId.value)
  if (result.code === 200) {
    ElMessage.success('取消订单成功')
    // 重新获取订单详情数据
    getOrderDetail()
  } else {
    ElMessage.error(result.message)
  }
}
// 返回挂号页按钮的回调
const goBooking = () => {
  router.replace({
    name: 'registerStepOne',
    query: {
      hoscode: orderInfo.value?.hoscode,
      depcode: orderInfo.value?.depcode,
    },
  })
}
// 查看全部订单的回调
const goAllOrder = () => {
  router.replace('/user/order')
}
// 组件挂载时获取当前订单数据
onMounted(() => {
  // 获取当前订单数据
  getOrderDetail()
})
</script>

<style scoped lang="scss">
.container {
  :deep(.el-card) {
    color: $base-color;
    .card-header {
      font-size: 20px;
    }
    .content {
      .top {
        padding-bottom: 20px;
        border-bottom: 1px solid #e4e7ed;
        display: flex;
        justify-content: space-between;
        .info {
          width: 180px;
          height: 40px;
          text-align: center;
          display: flex;
          align-items: center;
          color: white;
          border-radius: 10px;
          background-color: #409eff;
          &.cancel {
            background-color: rgb(236, 83, 22);
            width: 120px;
          }
          &.success {
            background-color: rgb(65, 196, 65);
            width: 100px;
          }
        }
        .tips {
          width: 250px;
          display: flex;
          justify-content: space-between;
          img {
            width: 50px;
          }
          div {
            line-height: 25px;
            margin-left: 10px;
          }
        }
      }
      .center {
        margin-top: 20px;
        display: flex;
        justify-content: space-between;
        .left {
          width: 45%;
          height: 390px;
          .el-descriptions__label {
            width: 120px;
            font-weight: bold;
            color: $base-color;
          }
          .el-descriptions__content {
            color: $base-color;
            font-size: 16px;
          }
        }
        .right {
          width: 53%;
          height: 390px;
          .card-header {
            font-size: 16px;
          }
          ol {
            list-style-position: inside;
            list-style-type: decimal;
            li {
              margin-bottom: 10px;
              line-height: 23px;
              &:last-child {
                margin-bottom: 0;
              }
            }
          }
        }
      }
    }
    .bottom {
      display: flex;
      justify-content: end;
    }
  }
  :deep(.el-dialog__body) {
    padding: 20px;
    margin: 0 -16px;
    border-top: 1px solid #e4e7ed;
    border-bottom: 1px solid #e4e7ed;
    .content {
      display: flex;
      flex-direction: column;
      align-items: center;
      .qrCode {
        margin-bottom: 10px;
      }
      p {
        line-height: 25px;
        font-style: 16px;
      }
    }
  }
}
</style>
